#pragma once
#include "Engine/Engine.h"
#include "RenderTargetPool.h"
#include "FrameFlowDataManager.h"
#include "RenderGraphBuilder.h"
#include "SceneRendering.h"

enum class CurrentFrameStatus : uint8
{
    PresentStatus,
    InterpolateStatus
};

class FramePrediction
{
public:
    FramePrediction();

    virtual ~FramePrediction();

    FRAMEPREDICTIONMODULE_API static void OnSetEnable(bool Enable);

    void OnPostEngineInit();

    void InitFF();

    void OnSlateWindowRendered(SWindow& SlateWindow, void* ViewportRHIPtr);

    /*
     * UE CopyToResolveTarget���������������RenderTargetΪcopy dest, ����ṩ@param IsSetSourceFrameBuffer����
     * �Ƿ�Ҫ����RenderTargetΪcopy src
     */
    void CopyTexture(FRHITexture* Source, FRHITexture* Dest, bool IsSetSourceFrameBuffer, FResolveParams ResolveParams);

    void FrameFlowDrawFrame();

    void InterpolateFrameEx(FRDGBuilder& GraphBuilder, const FViewInfo& View);

    void OnPostPostProcessingCallback(FRDGBuilder& GraphBuilder);

    /*
     * UE�ӿڻ�ȡ��������󲢷�������˵õ�gl_Position�ľ�����Ҫ��Բ�ͬ��RHI������
     * ����OpenGL����ProjectionSignY = -1.0f��MinClipZ = -1.0f
     * �����ȡ�����ͼ��Ҫ��ת������Ҫ��ProjectionSignY��Ϊ1.0f
     */
    inline FMatrix AdjustProjectionMatrix(const FMatrix& InProjectionMatrix)
    {
        float ProjectionSignY = -1.0f;
        float MinClipZ = -1.0f;
        FScaleMatrix ClipSpaceFixScale(FVector(1.0f, ProjectionSignY, 1.0f - MinClipZ));
        FTranslationMatrix ClipSpaceFixTranslate(FVector(0.0f, 0.0f, MinClipZ));
        return InProjectionMatrix * ClipSpaceFixScale * ClipSpaceFixTranslate;
    }

private:
    static void UpdateEnableFromSetting();

private:
    TRefCountPtr<IPooledRenderTarget> FFOutputRT;
    TRefCountPtr<IPooledRenderTarget> FFDepthRT;
    FMatrix ViewMatrix;
    FMatrix ProjectionMatrix;
    FMatrix ViewProjectionMatrix;
    FMatrix InvViewProjectionMatrix;
    FrameFlowDataManager FFDataManager;

    static bool bEnable;
    static bool bRealFrame;
    static bool bColorBufferInit;
    static bool bNativeFFInit;
};

